﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace UCLibrary.UC
{
    public partial class UCGear : UserControl
    {
        System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
        public UCGear()
        {
            InitializeComponent();
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            timer.Interval = 50;
            timer.Tick += T_tick;
            if(IsRotate)
            timer.Start();
        }
        //是否旋转
        private bool isRotate = false;
        [Description("置为真旋转")]
        public bool IsRotate
        {
            get { return isRotate; }
            set
            { 
                isRotate = value;
                if (value)
                    timer.Start();
                else 
                    timer.Stop();
                Refresh(); 
            }
        } 
        private Color gearColor = Color.DarkOrange;
        [Category("自定/颜色"),Description("设定齿轮的颜色")]
        public Color GearColor
        {
            get { return gearColor; }
            set { gearColor = value; Refresh(); }
        }
        private Color dotColor= Color.Black;
        [Category("自定/颜色"), Description("设定轴的颜色")]
        public Color DotColor
        {
            get { return dotColor; }
            set { dotColor = value; Refresh(); }
        }
        private Color back_Color = Color.Black;
        [Category("自定/颜色"), Description("设定壳子的颜色")]
        public Color Back_Color
        {
            get { return back_Color; }
            set { back_Color = value; Refresh(); }
        }
        private bool reversal = false;
        [Category("自定/方向"),Description("切换旋转方向")]
        public bool Reversal
        {
            get { return reversal; }
            set { reversal = value; Refresh(); } 
        }
        private float transSpeed = 5f;
        public float TransSpeed
        {
            get => transSpeed;
            set { transSpeed = value; Refresh(); }
        }
        public enum Direction
        {
            H,V
        }
        private Direction _direction= Direction.V;
        [Category("自定/方向"),Description("设定控件横向还是纵向")]
        public Direction Dir
        {
            get { return _direction; }
            set { _direction = value; Refresh(); }
        }
        private float angle = 0f;
        private void T_tick(object sender, EventArgs e)
        {
            angle += transSpeed*(-2*Convert.ToInt16(Reversal)+1);
            if(angle>=360)
                angle = 0f;
            Refresh();
        }
        private int gearNum = 10;
        public int GearNum
        {
            get { return gearNum; }
            set { gearNum = value; Refresh(); }
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;
            //圆宽,圆高
            float f1=0,f2=0;
            switch(Dir)
            {
                case Direction.V:
                    if (Width * 2 > Height)
                    {
                        f1 = Height / 2;
                        f2 = Height;
                    }
                    else
                    {
                        f1 = Width;
                        f2 = Width * 2;
                    }
                    break;
                    case Direction.H:
                    if (Height*2 < Width)
                    {
                        f1 = Height;
                        f2 = Height*2;
                    }
                    else
                    {
                        f1 = Width/2;
                        f2 = Width;
                    }
                    g.TranslateTransform(0,f1);
                    g.RotateTransform(-90);
                    break;
            }
            PaintMain(g, f1, f2);

        }
        private void PaintMain(Graphics g,float width,float height)
        {
            GraphicsPath shellPath = new GraphicsPath();
            GraphicsPath shellPath1 = new GraphicsPath();
            shellPath.AddArc(new RectangleF(0,0,width-1,(height-1)/2),180,180);
            shellPath.AddLine(width-1,width/2,width-1,3*(height-1)/2);
            shellPath.AddArc(new RectangleF(0,(height-1)/2,width-1,(height-1)/2), 0, 180);
            shellPath.CloseAllFigures();
            //大圆的半径
            float circleRadius = 3*width/8;
            //小圆的半径
            float circleRadius_s = width/4;
            //大圆取点
            List<PointF> bigPoints = new List<PointF>();
            List<PointF> smartPoints = new List<PointF>();
            List<PointF> points = new List<PointF>();
            List<PointF> center = new List<PointF>();
            //大圆点数
            int dotNum_b = GearNum;
            int dotNum_s = 2 * dotNum_b;

            //上圆心
            PointF centerpoint = new PointF(width/2, 11*height/32);
            for (int i = 0; i < dotNum_b; i++)
            {
                var x = i * 360 / dotNum_b;
                bigPoints.Add(Function.GetCirclePoint(centerpoint, circleRadius, x));
                center.Add(Function.GetCirclePoint(centerpoint, circleRadius_s / 4, x));
            }
            for (int i = 0; i < dotNum_s; i++)
            {
                var x = i * 360 / dotNum_s;
                smartPoints.Add(Function.GetCirclePoint(centerpoint, circleRadius_s, x));
            }
            for (int i = 0; i < dotNum_b; i++)
            {
                points.Add(bigPoints[i]);
                points.Add(smartPoints[i * 2 + 1]);
            }
            Function.setHighQuality(g);
            PathGradientBrush pg = new PathGradientBrush(shellPath);
            pg.CenterColor = Color.White;
            pg.SurroundColors = new Color[]
            {
                back_Color
            };
            g.FillPath(pg, shellPath);

            pg = new PathGradientBrush(points.ToArray());
            pg.CenterColor = DotColor;
            pg.SurroundColors = new Color[]
            {
                gearColor
            };
            pg.CenterPoint = centerpoint;

            g.TranslateTransform(centerpoint.X, centerpoint.Y);
            g.RotateTransform(angle);
            g.TranslateTransform(-centerpoint.X, -centerpoint.Y);
            g.FillClosedCurve(pg, points.ToArray());
            g.FillClosedCurve(new SolidBrush(DotColor), center.ToArray());
            g.TranslateTransform(centerpoint.X, centerpoint.Y);
            g.RotateTransform(-angle);
            g.TranslateTransform(-centerpoint.X, -centerpoint.Y);
            g.TranslateTransform(0, 2 * circleRadius - height / 16);
            g.TranslateTransform(centerpoint.X, centerpoint.Y);
            g.RotateTransform(-angle - 360 / gearNum / 2);
            g.TranslateTransform(-centerpoint.X, -centerpoint.Y);
            g.FillClosedCurve(pg, points.ToArray());
            g.FillClosedCurve(new SolidBrush(DotColor), center.ToArray());
            g.ResetTransform();
        }
    }
}
